/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.mydomain.debtbook;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;

/**
 * Demonstrates expandable lists backed by Cursors
 */
public class NewDebtActivity extends Activity {

	private ContactAccessor mContactAccessor;
	private DebtAdapter debtAdapter;
	private Cursor debtCursor;
	private ContactInfo selectedContact;

	private EditText lenderEdit;
	private EditText borrowerEdit;
	private EditText debtAmountEdit;
	private EditText categoryEdit;
	private EditText descriptionEdit;
	private EditText dateEdit;

	private ImageView expandLender;
	private ImageView expandDebtAmount;
	private ImageView expandBorrower;
	private ImageView expandCategory;
	private ImageView expandDescription;
	private ImageView expandDate;

	private ListView lenderListView;
	private ListView borrowerListView;

	private Button submit;
	private Button clear;

	private String missing;
	private String strDate;

	private boolean groupFlagLender;
	private boolean groupFlagBorrower;

	private static final int LENDER_REQUEST = 0;
	private static final int BORROWER_REQUEST = 1;
	private static final int CATEGORY_REQUEST = 2;

	private static final int MY_ERROR_DIALOG = 0;
	private static final int MY_DATE_PICKER_DIALOG = 1;

	private static final int WEIGHT_DOLLAR = 0;
	private static final int WEIGHT_PERCENT = 1;
	private static final int WEIGHT_VALUE = 2;

	private OnClickListener myClickListener;

	private ArrayList<String> lenderList;
	private HashMap<String, HashMap<String, String>> lenderListWeight;

	private ArrayList<String> borrowerList;
	private HashMap<String, HashMap<String, String>> borrowerListWeight;

	private HashSet lenderSplitable;
	private HashSet borrowerSplitable;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		intitalizeAccessors();
		initalizeView();
		initalizeListener();
		groupFlagLender = false;
		groupFlagBorrower = false;

	}

	private void intitalizeAccessors() {
		mContactAccessor = ContactAccessor.getInstance();
		debtAdapter = ((debtBookApplication) this.getApplication())
				.getDatabaseAdapter();
	}

	private void initalizeView() {
		setContentView(R.layout.new_debt);
		lenderEdit = (EditText) findViewById(R.id.nd_lenderEdit);
		borrowerEdit = (EditText) findViewById(R.id.nd_borrowerEdit);
		debtAmountEdit = (EditText) findViewById(R.id.nd_debtAmountEdit);
		categoryEdit = (EditText) findViewById(R.id.nd_categoryEdit);
		descriptionEdit = (EditText) findViewById(R.id.nd_descriptionEdit);
		dateEdit = (EditText) findViewById(R.id.nd_dateEdit);

		expandLender = (ImageView) findViewById(R.id.nd_expandLender);
		expandDebtAmount = (ImageView) findViewById(R.id.nd_expandDebtAmount);
		expandBorrower = (ImageView) findViewById(R.id.nd_expandBorrower);
		expandCategory = (ImageView) findViewById(R.id.nd_expandCategory);
		expandDescription = (ImageView) findViewById(R.id.nd_expandDescription);
		expandDate = (ImageView) findViewById(R.id.nd_expandDate);

		submit = (Button) findViewById(R.id.nd_submitButton);
		clear = (Button) findViewById(R.id.nd_clearButton);

		dateEdit.setText(DateFormat.getDateInstance().format(
				Calendar.getInstance().getTime()));

	}

	private void initalizeListener() {
		myClickListener = new OnClickListener() {
			@Override
			public void onClick(View v) {

				if (v == expandLender) {

					pickContact(LENDER_REQUEST);

				} else if (v == expandBorrower) {

					pickContact(BORROWER_REQUEST);

				} else if (v == expandDebtAmount) {
					showDebtPicker();
				} else if (v == expandCategory) {
					showCategoryPicker();
				} else if (v == expandDescription) {
					showDescriptionPicker();
				} else if (v == expandDate) {
					showDialog(MY_DATE_PICKER_DIALOG);
				} else if (v == submit) {
					submitDebt();
					finish();
				} else if (v == clear) {
					clearFields();
				} else if (v == lenderEdit) {
					pickContactWeight(LENDER_REQUEST);

				} else if (v == borrowerEdit) {
					pickContactWeight(BORROWER_REQUEST);
				}
			}
		};

		expandLender.setOnClickListener(myClickListener);
		expandBorrower.setOnClickListener(myClickListener);
		expandDebtAmount.setOnClickListener(myClickListener);
		expandDescription.setOnClickListener(myClickListener);
		expandCategory.setOnClickListener(myClickListener);
		expandDate.setOnClickListener(myClickListener);

		borrowerEdit.setOnClickListener(myClickListener);
		lenderEdit.setOnClickListener(myClickListener);

		submit.setOnClickListener(myClickListener);
		clear.setOnClickListener(myClickListener);

	}

	private void clearFields() {

		lenderEdit.setText("");
		borrowerEdit.setText("");
		debtAmountEdit.setText("");
		descriptionEdit.setText("");
	}

	private void showCategoryPicker() {
		startActivityForResult(new Intent(this, ListCategoryActivity.class),
				CATEGORY_REQUEST);
	}

	private void showDescriptionPicker() {

	}

	private void showDebtPicker() {

	}

	private void pickContact(int request) {

		startActivityForResult(new Intent(this, ListContactTabActivity.class),
				request);

	}

	private double convertWeightUnit(String inputStr, String unitFrom,
			String unitTo, double debtAmount, double debtSplit) {

		double input;

		if (inputStr != null && inputStr.length() != 0) {
			input = Double.valueOf(inputStr);
		} else {
			return -1;
		}

		if (unitFrom == "$" && unitTo == "%") {

			return input / debtAmount;

		} else if (unitFrom == "#" && unitTo == "%") {

			return input * debtSplit / debtAmount;

		}
		return input;
	}

	private void pickContactWeight(int request) {

		double debtAmount;
		String debtString = debtAmountEdit.getText().toString();

		if (debtString.length() == 0) {
			debtAmount = 0;
		} else {
			debtAmount = Double.valueOf(debtString);
		}

		if (request == LENDER_REQUEST) {

			if (lenderList != null) {

				startActivityForResult(
						new Intent(this, ListContactWeightActivity.class)
								.putExtra("ContactList", lenderList)
								.putExtra("ContactListWeight", lenderListWeight)
								.putExtra("DebtAmount", debtAmount)
								.putExtra("Splitable", lenderSplitable),
						request);
			}
		} else if (request == BORROWER_REQUEST) {

			if (borrowerListWeight != null) {

				startActivityForResult(
						new Intent(this, ListContactWeightActivity.class)
								.putExtra("ContactList", borrowerList)
								.putExtra("ContactListWeight",
										borrowerListWeight)
								.putExtra("DebtAmount", debtAmount)
								.putExtra("Splitable", borrowerSplitable),
						request);
			}

		}

	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if ((requestCode == LENDER_REQUEST) && resultCode == RESULT_OK) {

			Bundle extras = data.getExtras();
			if (data.hasExtra("ContactList")) {
				groupFlagLender = false;
				lenderListWeight = (HashMap<String, HashMap<String, String>>) extras
						.get("ContactListWeight");
				lenderList = data.getStringArrayListExtra("ContactList");
				lenderSplitable = (HashSet) extras.get("Splitable");
				if (lenderList.size() == 1) {
					lenderEdit.setText(lenderList.get(0));
					lenderEdit.setFocusable(true);
				} else {
					lenderEdit.setText("Multiple Names");
					lenderEdit.setFocusable(false);
				}

			} else if (data.hasExtra("GroupList")) {

				groupFlagLender = true;
				lenderListWeight = (HashMap<String, HashMap<String, String>>) extras
						.get("GroupListWeight");
				lenderEdit.setFocusable(false);
				lenderList = data.getStringArrayListExtra("GroupList");
				lenderSplitable = (HashSet) extras.get("Splitable");

				if (lenderList.size() == 1) {
					lenderEdit.setText(lenderList.get(0));
				} else {
					lenderEdit.setText("Multiple Groups");

				}
			}

		} else if (requestCode == BORROWER_REQUEST && resultCode == RESULT_OK) {
			Bundle extras = data.getExtras();

			if (data.hasExtra("ContactList")) {
				groupFlagBorrower = false;
				borrowerListWeight = (HashMap<String, HashMap<String, String>>) extras
						.get("ContactListWeight");
				borrowerList = data.getStringArrayListExtra("ContactList");
				borrowerSplitable = (HashSet) extras.get("Splitable");

				if (borrowerList.size() == 1) {
					borrowerEdit.setText(borrowerList.get(0));
					borrowerEdit.setFocusable(true);
				} else {
					borrowerEdit.setText("Multiple Names");
					borrowerEdit.setFocusable(false);
				}

			} else if (data.hasExtra("GroupList")) {
				groupFlagBorrower = true;
				borrowerListWeight = (HashMap<String, HashMap<String, String>>) extras
						.get("GroupListWeight");
				borrowerList = data.getStringArrayListExtra("GroupList");
				borrowerSplitable = (HashSet) extras.get("Splitable");
				if (borrowerList.size() == 1) {
					borrowerEdit.setText(borrowerList.get(0));
					borrowerEdit.setFocusable(true);
				} else {	
					borrowerEdit.setText("Multiple Names");
					borrowerEdit.setFocusable(false);
				}

			}

		}

		else if (requestCode == CATEGORY_REQUEST && resultCode == RESULT_OK) {

			String item = data.getStringExtra("ItemId");

			categoryEdit.setText(item);
		}
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case MY_ERROR_DIALOG:

			return new AlertDialog.Builder(this)
					.setTitle("Error")
					.setMessage("You have not enter a value for: " + missing)
					.setPositiveButton("Ok",
							new DialogInterface.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog,
										int arg1) {
								}
							}).create();
		case MY_DATE_PICKER_DIALOG:
			DatePickerDialog dateDlg = new DatePickerDialog(this,
					new DatePickerDialog.OnDateSetListener() {

						@Override
						public void onDateSet(DatePicker view, int year,
								int monthOfYear, int dayOfMonth) {
							GregorianCalendar chosenDate = new GregorianCalendar(
									year, monthOfYear, dayOfMonth);

							dateEdit.setText(DateFormat.getDateInstance()
									.format(chosenDate.getTime()));

						}
					}, 2011, 1, 1);

			dateDlg.setMessage("When did this debt happen?");

			return dateDlg;

		}
		return null;
	}

	@Override
	protected void onPrepareDialog(int id, Dialog dialog) {
		super.onPrepareDialog(id, dialog);
		switch (id) {
		case MY_ERROR_DIALOG:
			break;
		case MY_DATE_PICKER_DIALOG:
			DatePickerDialog dateDlg = (DatePickerDialog) dialog;
			Calendar cal = Calendar.getInstance();
			dateDlg.updateDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),
					cal.get(Calendar.DAY_OF_MONTH));

		}
	}

	private void submitDebt() {

		String debt = debtAmountEdit.getText().toString();
		String category = categoryEdit.getText().toString();
		String description = descriptionEdit.getText().toString();
		String dateCreate = dateEdit.getText().toString();
		if (lenderList.size() == 0 || borrowerList.size() == 0
				|| debt.length() == 0) {
			missing = "";
			if (lenderList.size() == 0) {
				missing += "Lender,";
			}
			if (borrowerList.size() == 0) {
				missing += "Borrower,";
			}
			if (debt.length() == 0) {
				missing += "Debt,";
			}
			missing = missing.substring(0, missing.length() - 1);
			showDialog(MY_ERROR_DIALOG);

		} else {

			if (category.length() == 0) {
				category = "Uncategorized";
			}

			double lenderDebt;
			double borrowerPercent;
			String borrower;
			String lender;
			String lenderChild;
			String borrowerChild;

			int lenderSize;
			int borrowerSize;
			int lenderGroupSize;
			int borrowerGroupSize;

			for (int i = 0; i < lenderList.size(); i++) {

				lender = lenderList.get(i);
				if (lenderListWeight.get(lender).get("weight") != null
						&& lenderListWeight.get(lender).get("weight").length() != 0) {

					lenderDebt = Double.valueOf(lenderListWeight.get(lender)
							.get("weight"));
				} else {

					lenderDebt = Double.valueOf(debt) / lenderList.size();
				}

				for (int j = 0; j < borrowerList.size(); j++) {

					borrower = borrowerList.get(j);

					if (borrowerListWeight.get(borrower).get("weight") != null
							&& borrowerListWeight.get(borrower).get("weight")
									.length() != 0) {

						borrowerPercent = convertWeightUnit(
								borrowerListWeight.get(borrower).get("weight"),
								borrowerListWeight.get(borrower).get(
										"weightUnit"), "%", lenderDebt,
								Double.valueOf(debt) / borrowerList.size());

					} else {
						borrowerPercent = 1.0 / borrowerList.size();
					}

					if (groupFlagLender) {

						Cursor lenderPersonInGroup = debtAdapter
								.getAllPersonForGroup(lender);
						int nameIndex = lenderPersonInGroup
								.getColumnIndex(DebtAdapter._NAME);
						lenderGroupSize = lenderPersonInGroup.getCount();

						while (lenderPersonInGroup.moveToNext()) {

							lenderChild = lenderPersonInGroup
									.getString(nameIndex);
							if (groupFlagBorrower) {

								Cursor borrowerPersonInGroup = debtAdapter
										.getAllPersonForGroup(borrower);
								borrowerGroupSize = borrowerPersonInGroup
										.getCount();

								while (borrowerPersonInGroup.moveToNext()) {
									borrowerChild = borrowerPersonInGroup
											.getString(nameIndex);

									ContentValues debtValues = new ContentValues();
									debtValues.put(DebtAdapter._LENDER,
											lenderChild);
									debtValues.put(DebtAdapter._BORROWER,
											borrowerChild);
									debtValues.put(DebtAdapter._CATEGORY,
											category);
									debtValues.put(DebtAdapter._DESCRIPTION,
											description);
									debtValues.put(DebtAdapter._CREATE_DATE,
											dateCreate);
									debtValues
											.put(DebtAdapter._DEBT,
													String.format(
															"%.2f",
															lenderDebt
																	* (borrowerPercent / lenderGroupSize)
																	/ borrowerGroupSize));
									debtAdapter.insertDebt(debtValues);

								}
							} else {
								ContentValues debtValues = new ContentValues();
								debtValues
										.put(DebtAdapter._LENDER, lenderChild);
								debtValues.put(DebtAdapter._BORROWER, borrower);
								debtValues.put(DebtAdapter._CATEGORY, category);
								debtValues.put(DebtAdapter._DESCRIPTION,
										description);
								debtValues.put(DebtAdapter._CREATE_DATE,
										dateCreate);
								debtValues.put(
										DebtAdapter._DEBT,
										String.format("%.2f", lenderDebt
												* borrowerPercent
												/ lenderGroupSize));
								debtAdapter.insertDebt(debtValues);
							}

						}

					} else {
						ContentValues debtValues = new ContentValues();
						debtValues.put(DebtAdapter._LENDER, lender);
						debtValues.put(DebtAdapter._BORROWER, borrower);
						debtValues.put(DebtAdapter._CATEGORY, category);
						debtValues.put(DebtAdapter._DESCRIPTION, description);
						debtValues.put(DebtAdapter._CREATE_DATE, dateCreate);
						debtValues.put(
								DebtAdapter._DEBT,
								String.format("%.2f", lenderDebt
										* borrowerPercent));
						debtAdapter.insertDebt(debtValues);
					}

				}
			}

		}

	}
}